<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <link rel="shortcut icon" href="pingpong.png">
    <link rel="stylesheet" type="text/css" href="pingpong.css">
    <title>Ajax</title>
</head>
<body>

<div id="field">
    <div id="player2" class="player"></div>
    <div id="player1" class="player"></div>
    <div id="ball"></div>
</div>
<div id="scoreBoard">
    0 - 0
</div>

<script type="text/javascript" src="jQuery/jquery-1.9.1.js"></script>

<script type="text/javascript">
    (function() {

        var $field = $('#field');
        var $ball = $('#ball');
        var $player1 = $('#player1');
        var $player2 = $('#player2');
        var $scoreBoard = $('#scoreBoard');

        var callback =  function(player1Left, player2Left, ballTop, ballLeft, score1, score2) {
            $ball.css('left', ballLeft);
            $ball.css('top', ballTop);
            $player1.css('left', player1Left);
            $player2.css('left', player2Left);
            $scoreBoard.text(score1 + ' - ' + score2);
        };
        var controller = new PingPongJsController(callback);

        $field.mousemove(function(event) {
            controller.playerMoved(event.pageX);
        });

        function Ball(x, y, size, speed, angle) {
            this.x = x;
            this.y = y;
            this.size = size;
            this.speed = speed;
            this.setAngle = function (angle) {
                this.angle = angle;
                this.velocityX = Math.cos(this.angle * Math.PI / 180) * this.speed;
                this.velocityY = Math.sin(this.angle * Math.PI / 180) * this.speed;
            }

            this.setAngle(angle);
        }

        function Player(height, width, padding, left) {
            this.height = height;
            this.width = width;
            this.padding = padding;
            this.left = left;
            this.previousLeft = left;
            this.speed = 0;
        }

        function PingPongJsController(callback) {

            this.playerMoved = function(x) {
                player1.left = x - 100 - player1.width / 2;
                player2.left = x - 100 - player1.width / 2;
            };

            function recalculatePositions() {

                player1.speed = player1.left - player1.previousLeft;
                player2.speed = player2.left - player2.previousLeft;
                player1.previousLeft = player1.left;
                player2.previousLeft = player2.left;

                ball.x = ball.x + ball.velocityX;
                ball.y = ball.y + ball.velocityY;

                if (ball.y <= player2.height + player2.padding && ball.y
                        >= player2.height + player2.padding - ball.speed) {
                    if (ball.x < player2.left + player2.width && ball.x + ball.size > player2.left) {
                        ball.setAngle(360 - ball.angle);
                    }
                }

                if (ball.y >= fieldHeight - player1.height - player1.padding - ball.size
                        && ball.y <= fieldHeight - player1.height - player1.padding  - ball.size + ball.speed) {
                    if (ball.x < player1.left + player1.width && ball.x + ball.size > player1.left) {
                        ball.setAngle(360 - ball.angle + player1.speed / ball.speed * 20);
                    }
                }

                if (ball.y <= 0) {
                    score1++;
                    goal();
                }

                if (ball.y >= fieldHeight - ball.size) {
                    score2++;
                    goal();
                }

                if (ball.x <= 0 || ball.x >= fieldWidth - ball.size) {
                    if (ball.angle >= 0 && ball.angle < 180) {
                        ball.setAngle(180 - ball.angle);
                    }
                    if (ball.angle >= 180 && ball.angle < 360) {
                        ball.setAngle(270 * 2 - ball.angle);
                    }
                }
                callback(player1.left, player2.left, ball.y, ball.x, score1, score2);
            }

            var xStart = 100;
            var xEnd = 500;
            var ball = new Ball(190, 240, 20, 8, getStartingAngle());
            var player1 = new Player(20, 100, 5, (xEnd - xStart - 100) / 2);
            var player2 = new Player(20, 100, 5, (xEnd - xStart - 100) / 2);
            var fieldHeight = 500;
            var fieldWidth = 400;
            var score1 = 0;
            var score2 = 0;

            function goal() {
                ball = new Ball(190, 240, 20, 8, getStartingAngle());
            }

            function getStartingAngle() {
                var random = Math.random();
                if (random <= 0.5) {
                    return 45 + 180 * random;
                } else {
                    return 225 + 180 * (1 - random);
                }
            }

            setInterval(recalculatePositions, 1);
        }

    })();
</script>

</body>
</html>